#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
增强的日志记录模块
为所有API端点提供详细的调试信息
"""

import logging
import json
import traceback
from datetime import datetime
from typing import Any, Dict, Optional
from functools import wraps

class APILogger:
    """API日志记录器"""
    
    def __init__(self, logger_name: str = 'api'):
        self.logger = logging.getLogger(logger_name)
        
    def log_request(self, method: str, path: str, params: Optional[Dict] = None, body: Optional[Any] = None):
        """记录API请求"""
        log_data = {
            'timestamp': datetime.now().isoformat(),
            'method': method,
            'path': path,
            'params': params,
            'body': self._safe_serialize(body) if body else None
        }
        self.logger.info(f"[API请求] {method} {path}")
        self.logger.debug(f"[API请求详情] {json.dumps(log_data, ensure_ascii=False, indent=2)}")
        
    def log_response(self, path: str, status: int, response: Any, duration_ms: float = None):
        """记录API响应"""
        log_data = {
            'timestamp': datetime.now().isoformat(),
            'path': path,
            'status': status,
            'response': self._safe_serialize(response),
            'duration_ms': duration_ms
        }
        
        if status >= 200 and status < 300:
            self.logger.info(f"[API响应] {path} - 状态: {status} - 耗时: {duration_ms:.2f}ms")
        elif status >= 400 and status < 500:
            self.logger.warning(f"[API客户端错误] {path} - 状态: {status}")
        else:
            self.logger.error(f"[API服务器错误] {path} - 状态: {status}")
            
        self.logger.debug(f"[API响应详情] {json.dumps(log_data, ensure_ascii=False, indent=2)}")
        
    def log_error(self, path: str, error: Exception, context: Optional[Dict] = None):
        """记录API错误"""
        error_data = {
            'timestamp': datetime.now().isoformat(),
            'path': path,
            'error_type': type(error).__name__,
            'error_message': str(error),
            'traceback': traceback.format_exc(),
            'context': context
        }
        self.logger.error(f"[API错误] {path} - {type(error).__name__}: {str(error)}")
        self.logger.debug(f"[API错误详情] {json.dumps(error_data, ensure_ascii=False, indent=2)}")
        
    def log_database_operation(self, operation: str, table: str, affected_rows: int = None, duration_ms: float = None):
        """记录数据库操作"""
        log_data = {
            'timestamp': datetime.now().isoformat(),
            'operation': operation,
            'table': table,
            'affected_rows': affected_rows,
            'duration_ms': duration_ms
        }
        self.logger.debug(f"[数据库操作] {operation} {table} - 影响行数: {affected_rows} - 耗时: {duration_ms:.2f}ms")
        
    def log_evaluation(self, eval_type: str, conversation_id: str, score: int, reason: str = None):
        """记录评估操作"""
        log_data = {
            'timestamp': datetime.now().isoformat(),
            'evaluation_type': eval_type,
            'conversation_id': conversation_id,
            'score': score,
            'reason': reason
        }
        self.logger.info(f"[评估] 类型: {eval_type} - 对话ID: {conversation_id} - 分数: {score}")
        if reason:
            self.logger.debug(f"[评估原因] {reason}")
            
    def log_feedback(self, conversation_id: str, score: int, suggestion: str = None, tags: list = None):
        """记录用户反馈"""
        log_data = {
            'timestamp': datetime.now().isoformat(),
            'conversation_id': conversation_id,
            'score': score,
            'suggestion': suggestion,
            'tags': tags
        }
        self.logger.info(f"[用户反馈] 对话ID: {conversation_id} - 分数: {score}")
        if suggestion:
            self.logger.debug(f"[反馈建议] {suggestion}")
        if tags:
            self.logger.debug(f"[反馈标签] {', '.join(tags)}")
            
    def log_prompt_update(self, prompt_type: str, old_length: int, new_length: int, source: str):
        """记录提示词更新"""
        self.logger.info(
            f"[提示词更新] 类型: {prompt_type} - 来源: {source} - "
            f"长度变化: {old_length} -> {new_length} ({new_length - old_length:+d})"
        )
        
    def log_sse_event(self, event_type: str, data: Any, client_id: str = None):
        """记录SSE事件"""
        log_data = {
            'timestamp': datetime.now().isoformat(),
            'event_type': event_type,
            'client_id': client_id,
            'data': self._safe_serialize(data)
        }
        self.logger.debug(f"[SSE事件] 类型: {event_type} - 客户端: {client_id}")
        
    def _safe_serialize(self, obj: Any) -> Any:
        """安全序列化对象"""
        try:
            # 尝试将对象转换为可序列化的格式
            if isinstance(obj, (str, int, float, bool, type(None))):
                return obj
            elif isinstance(obj, (list, tuple)):
                return [self._safe_serialize(item) for item in obj]
            elif isinstance(obj, dict):
                return {key: self._safe_serialize(value) for key, value in obj.items()}
            else:
                return str(obj)
        except Exception:
            return "<无法序列化>"


def api_endpoint(logger: APILogger):
    """API端点装饰器，自动记录请求和响应"""
    def decorator(func):
        @wraps(func)
        def wrapper(handler, *args, **kwargs):
            import time
            start_time = time.time()
            
            # 记录请求
            method = handler.command
            path = handler.path
            logger.log_request(method, path)
            
            try:
                # 执行原函数
                result = func(handler, *args, **kwargs)
                
                # 计算耗时
                duration_ms = (time.time() - start_time) * 1000
                
                # 记录响应
                logger.log_response(path, 200, result, duration_ms)
                
                return result
                
            except Exception as e:
                # 记录错误
                logger.log_error(path, e)
                raise
                
        return wrapper
    return decorator


def setup_enhanced_logging(log_level: str = 'DEBUG'):
    """设置增强的日志系统"""
    import os
    from logging.handlers import RotatingFileHandler
    
    # 创建logs目录
    if not os.path.exists('logs'):
        os.makedirs('logs')
    
    # 配置日志格式
    detailed_format = logging.Formatter(
        '%(asctime)s - [%(levelname)s] - %(name)s - %(funcName)s:%(lineno)d - %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    
    simple_format = logging.Formatter(
        '%(asctime)s - %(levelname)s - %(message)s',
        datefmt='%H:%M:%S'
    )
    
    # 配置文件处理器（详细日志）
    file_handler = RotatingFileHandler(
        'logs/api_debug.log',
        maxBytes=50*1024*1024,  # 50MB
        backupCount=10,
        encoding='utf-8'
    )
    file_handler.setLevel(logging.DEBUG)
    file_handler.setFormatter(detailed_format)
    
    # 配置控制台处理器（简洁日志）
    console_handler = logging.StreamHandler()
    console_handler.setLevel(getattr(logging, log_level))
    console_handler.setFormatter(simple_format)
    
    # 配置根日志器
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.DEBUG)
    root_logger.addHandler(file_handler)
    root_logger.addHandler(console_handler)
    
    # 创建专门的日志器
    api_logger = APILogger('api')
    db_logger = APILogger('database')
    eval_logger = APILogger('evaluation')
    
    return {
        'api': api_logger,
        'db': db_logger,
        'eval': eval_logger
    }


# 使用示例
if __name__ == "__main__":
    # 设置日志系统
    loggers = setup_enhanced_logging('INFO')
    
    # 测试日志记录
    api_logger = loggers['api']
    
    # 模拟API请求
    api_logger.log_request('GET', '/api/statistics', {'limit': 10})
    api_logger.log_response('/api/statistics', 200, {'total': 100}, 125.5)
    
    # 模拟错误
    try:
        raise ValueError("测试错误")
    except Exception as e:
        api_logger.log_error('/api/test', e, {'user_id': 123})
    
    # 模拟评估
    eval_logger = loggers['eval']
    eval_logger.log_evaluation('salary', 'conv_001', 85, '薪资询问时机恰当')
    
    # 模拟反馈
    eval_logger.log_feedback('conv_001', 9, '很好的评估', ['准确', '详细'])
